package au.edu.utas.yu_qiao_group.luckyman.ui.raffledetail;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.util.Calendar;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.library.baseAdapters.BR;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import au.edu.utas.yu_qiao_group.luckyman.MainActivity;
import au.edu.utas.yu_qiao_group.luckyman.R;
import au.edu.utas.yu_qiao_group.luckyman.databinding.FragmentRaffleDetailBinding;
import au.edu.utas.yu_qiao_group.luckyman.db.raffles.RaffleDTO;
import au.edu.utas.yu_qiao_group.luckyman.service.RaffleService;
import au.edu.utas.yu_qiao_group.luckyman.service.UserService;
import au.edu.utas.yu_qiao_group.luckyman.ui.raffleshome.SharedRaffleViewModel;
import au.edu.utas.yu_qiao_group.luckyman.utils.ValidationMessage;

public class RaffleDetailFragment extends Fragment {
  private static final String TAG = "RafflesDetail";
  private FragmentRaffleDetailBinding mBinding;
  private AlertDialog mAlertDialog;
  private SharedRaffleViewModel mSharedRaffleVm;
  private ImagePickerListener mImagePickerListener;
  private ImageView mImg;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    setHasOptionsMenu(true);
    ActionBar actionBar = ((MainActivity) getActivity()).getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);
    mSharedRaffleVm = new ViewModelProvider(getActivity()).get(SharedRaffleViewModel.class);
    AlertDialog.Builder ab = new AlertDialog.Builder(getContext());
    mAlertDialog = ab.create();
    mImagePickerListener = new ImagePickerListener(getContext(), getActivity(), this);
    super.onCreate(savedInstanceState);
  }

  @Override
  public View onCreateView(@NonNull LayoutInflater inflater,
                           ViewGroup container, Bundle savedInstanceState) {
    mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_raffle_detail, container, false);
    RaffleDetailViewModel vm = new RaffleDetailViewModel(new RaffleDTO());
    initViewModel(vm);
    mBinding.setRaffle(vm);
    View rootView = mBinding.getRoot();
    initSideEffects(rootView);
    return rootView;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
      getActivity().getSupportFragmentManager().popBackStack();
      return false;
    }
    return super.onOptionsItemSelected(item);
  }

  protected void initViewModel (RaffleDetailViewModel vm) {
    Context ctx = getActivity().getApplicationContext();
    // EDIT mode
    if (mSharedRaffleVm.getMode() == SharedRaffleViewModel.EDIT_MODE_KEY) {
      vm.cloneFrom(mSharedRaffleVm.getSelected());
    } else {
      // CREATE mode
      vm.setDrawTime(Calendar.getInstance().getTimeInMillis());
      vm.setOrganizer(UserService.getCurrentUserCompany(ctx.getSharedPreferences(MainActivity.KEY_DATA_PRIVATE, Context.MODE_PRIVATE)));
    }
  }

  protected void initSideEffects (View rootView) {
    mImg = rootView.findViewById(R.id.cover_preview);
    RaffleDetailViewModel vm = mBinding.getRaffle();
    // handle side-effects on edit mode
    if (mSharedRaffleVm.getMode() == SharedRaffleViewModel.EDIT_MODE_KEY) {
      // disable total amount edit
      EditText amountInput = rootView.findViewById(R.id.editText4);
      amountInput.setFocusable(false);
      amountInput.setFocusableInTouchMode(false);
      // disable margin raffle edit
      Switch marginSwitch = rootView.findViewById(R.id.switch1);
      marginSwitch.setClickable(false);
      // disable draw time edit
      EditText drawTimeInput = rootView.findViewById(R.id.editText7);
      drawTimeInput.setClickable(false);
      if(TextUtils.isEmpty(vm.getCover()) == false) {
        setImgBitmap(vm.getCover());
      }
    } else {
      // handle side-effects on create mode
      setDatePickerListener(rootView, vm);
    }
    mImg.setOnClickListener(mImagePickerListener);
    setSubmitButton(rootView);
  }

  protected void setDatePickerListener (View rootView, final RaffleDetailViewModel vm) {
    EditText t = rootView.findViewById(R.id.editText7);
    t.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        final Calendar c = Calendar.getInstance();
        c.setTimeInMillis(vm.getDrawTime());
        new DatePickerDialog(getActivity(), R.style.ThemeOverlay_MaterialComponents_Dialog, new DatePickerDialog.OnDateSetListener() {

          @Override
          public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            c.set(year, monthOfYear, dayOfMonth);
            vm.setDrawTime(c.getTimeInMillis());
            vm.notifyPropertyChanged(BR.drawTime);
          }
        }, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH)).show();
      }
    });
  }
  protected void setSubmitButton(View rootView) {
    Button btn = rootView.findViewById(R.id.submit_button);
    btn.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        RaffleDetailViewModel vm = mBinding.getRaffle();
        ValidationMessage validResult = validate(vm);
        if (validResult.getMIsValid() == ValidationMessage.INVALID_KEY){
          mAlertDialog.setMessage(validResult.getMInvalidMessage());
          mAlertDialog.show();
          return;
        }
        MainActivity activity = (MainActivity) getActivity();
        // EDIT mode
        if (mSharedRaffleVm.getMode() == SharedRaffleViewModel.EDIT_MODE_KEY) {
          boolean result = RaffleService.updateRaffle(activity.mDb, vm.getModel());
          if (result) {
            mAlertDialog.setMessage("Successfully updated raffle info: "+vm.getName());
            mAlertDialog.show();
            mAlertDialog.setOnDismissListener(onSubmitSuccess);
          } else {
            mAlertDialog.setMessage("Update FAILED, please check null options");
            mAlertDialog.show();
          }
        } else {
          // CREATE mode
          boolean result = RaffleService.insertRaffle(activity.mDb, vm.getModel());
          if (result) {
            mAlertDialog.setMessage("Successfully created new raffle: "+vm.getName());
            mAlertDialog.show();
            mAlertDialog.setOnDismissListener(onSubmitSuccess);
          } else {
            mAlertDialog.setMessage("Create FAILED, please check null options");
            mAlertDialog.show();
          }
        }
      }
    });
  }

  protected boolean setImgBitmap (String filename) {
    boolean success = false;
    try {
      FileInputStream io = new FileInputStream(new File(getContext().getExternalFilesDir("my_capture"), filename));
      mImg.setImageBitmap(BitmapFactory.decodeStream(io));
      success = true;
      io.close();
    } catch (Exception e) {
      Toast.makeText(getContext(), "failed to load image", Toast.LENGTH_SHORT).show();
    }
    return success;
  }
  @Override
  public void onActivityResult(int reqCode, int resCode, Intent data) {
    String filename = mImagePickerListener.onActivityResult(reqCode, resCode, data);
    RaffleDetailViewModel vm = mBinding.getRaffle();
    if (reqCode == ImagePickerListener.CROP_PHOTO && filename != null && vm != null && setImgBitmap(filename)) {
      vm.setCover(filename);
    }
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    mImagePickerListener.onRequestPermissionsResult(requestCode, permissions, grantResults);
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }

  protected ValidationMessage validate(final RaffleDetailViewModel vm) {
    if (TextUtils.isEmpty(vm.getName())) {
      return new ValidationMessage(ValidationMessage.INVALID_KEY, "Raffle name should not be empty");
    }
    if (TextUtils.isEmpty(vm.getBrief())) {
      return new ValidationMessage(ValidationMessage.INVALID_KEY, "Raffle brief should not be empty");
    }
    if (vm.getPrize() <= 0) {
      return new ValidationMessage(ValidationMessage.INVALID_KEY, "Prize should be greater than 0");
    }
    if (vm.getTotalAmount() <= 0 || vm.getTotalAmount() > 1000) {
      return new ValidationMessage(ValidationMessage.INVALID_KEY, "Total amount should be greater than 0 and less than 1000");
    }
    if (vm.getSingleLimit() <= 0 || vm.getSingleLimit() > vm.getTotalAmount()) {
      return new ValidationMessage(ValidationMessage.INVALID_KEY, "Single Limitation should be greater than 0 and less than total amount");
    }
    return new ValidationMessage(ValidationMessage.VALID_KEY, "");
  }

  protected final DialogInterface.OnDismissListener onSubmitSuccess = new DialogInterface.OnDismissListener() {
    @Override
    public void onDismiss(DialogInterface dialog) {
      Navigation.findNavController(mBinding.getRoot()).navigate(R.id.nav_raffles_home);
    }
  };
}
